package com.qumitech.visualnovel.service.novel;

import java.util.*;
import com.alibaba.fastjson.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import com.qumitech.visualnovel.model.common.BaseResponse;
import com.qumitech.visualnovel.datasource.editor.BookUserInfoDAOMapper;
import com.qumitech.visualnovel.datasource.editor.AuthorDAOMapper;
import com.qumitech.visualnovel.datasource.editor.BookDAOMapper;
import com.qumitech.visualnovel.datasource.editor.AuthorPolicyDAOMapper;
import com.qumitech.visualnovel.datasource.editor.BookInfoDAOMapper;

import com.qumitech.visualnovel.model.dao.editor.BookUserInfoDAO;
import com.qumitech.visualnovel.model.dao.editor.AuthorDAO;
import com.qumitech.visualnovel.model.dao.editor.AuthorPolicyDAO;
import com.qumitech.visualnovel.model.dao.editor.BookInfoDAO;

import com.qumitech.visualnovel.model.dto.AuthorQueryDTO;
import com.qumitech.visualnovel.model.dto.AuthorUpdateDTO;
import com.qumitech.visualnovel.model.dto.AuthorPolicyAddDTO;
import com.qumitech.visualnovel.model.dto.AuthorPolicyUpdateDTO;
import com.qumitech.visualnovel.model.dto.AuthorPolicyQueryDTO;
import com.qumitech.visualnovel.model.dto.AuthorIntroDTO;

@Slf4j
@Service
public class AuthorServiceImpl implements AuthorService {
    @Autowired
    BookUserInfoDAOMapper bookUserInfoDAOMapper;

    @Autowired
    AuthorDAOMapper authorDAOMapper;

    @Autowired
    BookDAOMapper bookDAOMapper;

    @Autowired
    AuthorPolicyDAOMapper authorPolicyDAOMapper;

    @Autowired
    BookInfoDAOMapper bookInfoDAOMapper;

    private AuthorPolicyDAO getAuthorPolicy(AuthorDAO author) {
        Long policyId = author.getPolicyId();
        if (policyId != null) {
            AuthorPolicyDAO record = authorPolicyDAOMapper.selectByPrimaryKey(policyId);
            if (record != null) {
                Date now = new Date();
                Date startAt = record.getStartAt();
                Date endAt = record.getEndAt();
                if (startAt!=null && endAt!=null && now.compareTo(startAt)>=0 && now.compareTo(endAt)<=0) {
                    return record;
                }
            }
        }

        String contractType = author.getContractType();
        AuthorPolicyDAO record = authorPolicyDAOMapper.getDefaultPolicy(contractType);
        return record;
    }

    @Override
    public BaseResponse listAuthor(AuthorQueryDTO param) {
        int total = authorDAOMapper.total(param);
        List<AuthorDAO> list = authorDAOMapper.list(param);

        BaseResponse result = new BaseResponse(new JSONArray(), total);
        for (AuthorDAO item : list) {
            BookUserInfoDAO uInfo = bookUserInfoDAOMapper.selectByPrimaryKey(item.getUid());
            JSONObject jItem = new JSONObject();
            jItem.put("id", item.getId());
            jItem.put("uid", item.getUid());
            jItem.put("name", item.getName());
            jItem.put("pseudonym", item.getPseudonym());
            jItem.put("sexuality", item.getSexuality());
            jItem.put("contractType", item.getContractType());
            jItem.put("country", item.getCountry());
            jItem.put("bookNum", bookDAOMapper.getEditStateNum(item.getUid(), null));
            jItem.put("registerAt", uInfo.getCreatedAt());
            result.getJSONArray("data").add(jItem);
        }
        return result;
    }

    @Override
    public BaseResponse detailAuthor(Integer uid) {
        BookUserInfoDAO uInfo = bookUserInfoDAOMapper.selectByPrimaryKey(uid);
        AuthorDAO author = authorDAOMapper.getAuthor(uid);

        JSONObject result = new JSONObject();
        result.put("id", author.getId());
        result.put("uid", uid);
        result.put("name", author.getName());
        result.put("pseudonym", author.getPseudonym());
        result.put("sexuality", author.getSexuality());
        result.put("contractType", author.getContractType());
        result.put("email", uInfo.getUsername());
        result.put("registerAt", uInfo.getCreatedAt());
        result.put("bookReleasedNum", bookDAOMapper.getEditStateNum(uid, "Completed"));
        result.put("bookOngoinNum", bookDAOMapper.getEditStateNum(uid, "Ongoing"));

        AuthorPolicyDAO policy = this.getAuthorPolicy(author);
        if (policy != null) {
            result.put("policy", policy.getName());
            result.put("base", policy.getBase());
            result.put("bonus", policy.getBonus());
            result.put("share", policy.getShare());
        }

        return new BaseResponse(result);
    }

    @Override
    public BaseResponse updateAuthor(AuthorUpdateDTO param) {
        AuthorDAO record = new AuthorDAO();
        record.setId(param.getId());
        record.setPolicyId(param.getPolicyId());
        record.setContractType(param.getContractType());
        authorDAOMapper.updateByPrimaryKeySelective(record);
        return new BaseResponse();
    }

    @Override
    public BaseResponse getAuthorIntro(Long bookId) {
        BookInfoDAO bookInfoDAO = bookInfoDAOMapper.selectRecord(bookId);

        JSONObject result = new JSONObject();
        if (bookInfoDAO != null) {
            result.put("book_id", bookInfoDAO.getBookId());
            result.put("signature", bookInfoDAO.getAuthorSignature());
            result.put("introduction", bookInfoDAO.getAuthorIntroduction());
        }
        return new BaseResponse(result);
    }

    @Override
    public BaseResponse updateAuthorIntro(AuthorIntroDTO body) {
        BookInfoDAO bookInfoDAO = bookInfoDAOMapper.selectRecord(body.getBookId());
        if (bookInfoDAO != null) {
            bookInfoDAO.setBookId(body.getBookId());
            bookInfoDAO.setAuthorSignature(body.getSignature());
            bookInfoDAO.setAuthorIntroduction(body.getIntroduction());
            bookInfoDAOMapper.updateByPrimaryKeySelective(bookInfoDAO);
        } else {
            bookInfoDAO = new BookInfoDAO();
            bookInfoDAO.setBookId(body.getBookId());
            bookInfoDAO.setAuthorSignature(body.getSignature());
            bookInfoDAO.setAuthorIntroduction(body.getIntroduction());
            bookInfoDAOMapper.insertSelective(bookInfoDAO);
        }
        return new BaseResponse();
    }

    @Override
    public BaseResponse addAuthorPolicy(AuthorPolicyAddDTO param) {
        AuthorPolicyDAO defaultPolicy = authorPolicyDAOMapper.getDefaultPolicy(param.getContractType());
        if (defaultPolicy!=null && param.getIfDefault()) {
            return new BaseResponse(-1, "默认政策已存在");
        }

        AuthorPolicyDAO record = new AuthorPolicyDAO();
        record.setName(param.getName());
        record.setContractType(param.getContractType());
        record.setBase(param.getBase());
        record.setBonus(param.getBonus());
        record.setShare(param.getShare());
        if (!param.getIfDefault()) {
            record.setStartAt(param.getStartAt());
            record.setEndAt(param.getEndAt());
        }
        record.setIfDefault(param.getIfDefault());
        authorPolicyDAOMapper.insertSelective(record);
        return new BaseResponse();
    }

    @Override
    public BaseResponse updateAuthorPolicy(AuthorPolicyUpdateDTO param) {
        AuthorPolicyDAO record = authorPolicyDAOMapper.selectByPrimaryKey(param.getId());
        record.setName(param.getName());
        record.setContractType(param.getContractType());
        record.setBase(param.getBase());
        record.setBonus(param.getBonus());
        record.setShare(param.getShare());
        if (!record.getIfDefault()) {
            record.setStartAt(param.getStartAt());
            record.setEndAt(param.getEndAt());
        }
        authorPolicyDAOMapper.updateByPrimaryKeySelective(record);
        return new BaseResponse();
    }

    @Override
    public BaseResponse delAuthorPolicy(Long id) {
        AuthorPolicyDAO record = authorPolicyDAOMapper.selectByPrimaryKey(id);
        if (record.getIfDefault()) {
            return new BaseResponse(-1, "默认政策不能删除");
        }
        authorPolicyDAOMapper.deleteByPrimaryKey(id);
        return new BaseResponse();
    }

    @Override
    public BaseResponse listAuthorPolicy(AuthorPolicyQueryDTO param) {
        int total = authorPolicyDAOMapper.total(param);
        List<AuthorPolicyDAO> list = authorPolicyDAOMapper.list(param);
        return new BaseResponse(list, total);
    }
}
